package com.ds.robot.assistant.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
 * 作用：
 *
 * @author WeiShaoying
 * 
 */
@SuppressWarnings("ALL")
public class JsonUtil {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        // 设置序列化输出时忽略空字段
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        // 其他配置
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);

        // 在反序列化时忽略 JSON 中对象中不存在的字段
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许 JSON 字符串使用单引号
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        // 允许未闭合的对象或数组
        // OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    }

    private JsonUtil() {
        // 防止外部构造
    }

    public static ObjectMapper getInstance() {
        return OBJECT_MAPPER;
    }

    /**
     * 将对象转换为 JSON 字符串。
     * 支持单个对象、List 和其他集合类型的序列化。
     *
     * @param obj 可能是单个对象、List 或其他集合
     * @return JSON 字符串
     * @throws JsonProcessingException 如果序列化失败
     */
    public static String toJson(Object obj) throws JsonProcessingException {
        return getInstance().writeValueAsString(obj);
    }

    /**
     * 将 JSON 字符串转换为指定类型的对象。
     *
     * @param json          JSON 字符串
     * @param typeReference 类型引用，用于反序列化集合类型
     * @param <T>           泛型类型
     * @return 转换后的对象
     * @throws JsonProcessingException 如果反序列化失败
     */
    public static <T> T fromJson(String json, TypeReference<T> typeReference) throws JsonProcessingException {
        return getInstance().readValue(json, typeReference);
    }

    /**
     * 将 JSON 字符串转换为指定类型的对象。
     *
     * @param json  JSON 字符串
     * @param clazz 目标类
     * @param <T>   泛型类型
     * @return 转换后的对象
     * @throws JsonProcessingException 如果反序列化失败
     */
    public static <T> T fromJson(String json, Class<T> clazz) throws JsonProcessingException {
        return getInstance().readValue(json, clazz);
    }

    public static void main(String[] args) throws Exception {
        try {
            // 单个对象序列化
            Person person = new Person("爱丽丝", false, 165.27D, 30);
            String json = JsonUtil.toJson(person);
            System.out.println(json);

            // List 序列化
            List<Person> people = new ArrayList<>();
            people.add(new Person("Bob", true, 180.85D, 25));
            people.add(new Person("Charlie", true, 178.55, 28));
            String jsonList = JsonUtil.toJson(people);
            System.out.println(jsonList);

            System.out.println("====================反序列化");

            // 反序列化单个对象
            Person deserializedPerson = JsonUtil.fromJson(json, Person.class);
            System.out.println(deserializedPerson);

            // 反序列化 List
            List<Person> deserializedPeople = JsonUtil.fromJson(jsonList, new TypeReference<List<Person>>() {
            });
            System.out.println(deserializedPeople);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class Person {

        private String name;
        private boolean sex;
        private Double height;
        private int age;
    }
}
